package com.mianyang.zhangsan.service.impl;

import com.mianyang.zhangsan.auth.config.RsaKeyProperties;
import com.mianyang.zhangsan.common.constant.SecConstant;
import com.mianyang.zhangsan.common.util.CacheHelper;
import com.mianyang.zhangsan.common.util.JwtUtils;
import com.mianyang.zhangsan.model.dto.SecLoginDto;
import com.mianyang.zhangsan.model.dto.SecRegisterDto;
import com.mianyang.zhangsan.model.entity.AccountDetail;
import com.mianyang.zhangsan.model.entity.SecAccount;
import com.mianyang.zhangsan.model.entity.SecAuthority;
import com.mianyang.zhangsan.service.ISecAccountService;
import com.mianyang.zhangsan.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * @author jiangjr
 * @date 2022-10-23
 */
@Component
public class LoginServiceImpl implements LoginService {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RsaKeyProperties properties;
    @Autowired
    private CacheHelper cacheHelper;
    @Autowired
    private ISecAccountService accountService;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Override
    public SecLoginDto login(SecAccount account) {
        // 使用authenticationManager进行登录校验
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(account.getAccountName(), account.getAccountWord());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (authenticate == null) {
            // 验证失败，返回校验失败信息
            throw new RuntimeException("用户名或是密码错误");
        }
        AccountDetail accountDetail = (AccountDetail) authenticate.getPrincipal();
        Long accountId = accountDetail.getAccount().getAccountId();
        // 验证成功，将用户信息存放redis
        cacheHelper.addValue(SecConstant.SEC_KEEP_LIVE_KEY + accountId, accountDetail,
                SecConstant.SEC_LOGIN_EXPIRE);
        // 获取验证通过的用户信息,返回token
        String token = JwtUtils.generateToken(accountDetail, properties.getPrivateKey());
        List<SecAuthority> authorities = accountService.selectCurrentAccountAuthority(accountId);
        SecLoginDto loginIfo = new SecLoginDto();
        loginIfo.setAccountId(accountId);
        loginIfo.setAccountName(account.getAccountName());
        loginIfo.setToken(token);
        loginIfo.setAuthorities(authorities);
        return loginIfo;
    }

    @Override
    public SecRegisterDto register(SecAccount account) {
        // 检查用户信息是否完整
        if (account.checkRegister()) {
            // 检查是否存在重复的用户
            SecAccount ac = accountService.selectAccountByUsername(account.getAccountName());
            if (ac != null) {
                return new SecRegisterDto("用户已经存在");
            }
            // 加密密码
            String encodePassword = passwordEncoder.encode(account.getAccountWord());
            account.setAccountWord(encodePassword);
            // 新增用户
            account.setRegisterTime(new Date());
            account.setAccountLevel(0);
            accountService.save(account);
            return new SecRegisterDto(account.getAccountId(), account.getAccountName(), "注册成功");
        }
        return new SecRegisterDto("请正确填写用户名或密码");

    }
}
